define([], function(){
	function asyncToGenerator(generatorFunc) {
	  return function () {
	    var gen = generatorFunc.apply(this, arguments);
	    return new Promise(function (resolve, reject) {
	      function step(key, arg) {
	        var generatorResult;
	
	        try {
	          generatorResult = gen[key](arg);
	        } catch (error) {
	          return reject(error);
	        } // gen.next() 得到的结果是一个 { value, done } 的结构        
	
	
	        var _generatorResult = generatorResult,
	            value = _generatorResult.value,
	            done = _generatorResult.done;
	
	        if (done) {
	          // 如果已经完成了 就直接resolve这个promise          
	          // 这个done是在最后一次调用next后才会为true          
	          // 以本文的例子来说 此时的结果是 { done: true, value: 'success' }          
	          // 这个value也就是generator函数最后的返回值          
	          return resolve(value);
	        } else {
	          // 除了最后结束的时候外，每次调用gen.next()          
	          // 其实是返回 { value: Promise, done: false } 的结构，          
	          // 这里要注意的是Promise.resolve可以接受一个promise为参数          
	          // 并且这个promise参数被resolve的时候，这个then才会被调用          
	          return Promise.resolve( // 这个value对应的是yield后面的promise            
	          value).then( // value这个promise被resove的时候，就会执行next            
	          // 并且只要done不是true的时候 就会递归的往下解开promise            
	          // 对应
	          //  gen.next().value.then(value => {            
	          //    gen.next(value).value.then(value2 => {            
	          //       gen.next()            
	          //            
	          //      
	          // 此时done为true了 整个promise被resolve了           
	          //      
	          // 最外部的test().then(res => console.log(res))的then就开始执行了            
	          //    })            
	          // })           
	          function onResolve(val) {
	            step("next", val);
	          }, // 如果promise被reject了 就再次进入step函数            
	          // 不同的是，这次的try catch中调用的是gen.throw(err)            
	          // 那么自然就被catch到 然后把promise给reject掉啦            
	          function onReject(err) {
	            step("throw", err);
	          });
	        }
	      }
	
	      step("next");
	    });
	  };
	}
	return asyncToGenerator;
});